﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.Json;

namespace ServerListerner.Helper
{
    public static class PublicEvent
    {
        private static JsonSerializerOptions option = new JsonSerializerOptions()
        {
            Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
        };
        public static string? GetDescription(this Enum value)
        {
            Type type = value.GetType();
            string name = Enum.GetName(type, value);
            if (name != null)
            {
                FieldInfo field = type.GetField(name);
                if (field != null)
                {
                    DescriptionAttribute? attr = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
                    if (attr != null)
                    {
                        return attr.Description;
                    }
                }
            }
            return string.Empty;
        }
        public static string ClearSpace(this string _str)
            => _str.Replace("\n", string.Empty)
            .Replace("\0", string.Empty)
            .Replace("\r", string.Empty)
            .Replace("\t", string.Empty)
            .Replace(" ", string.Empty);

        public static string ObjectToJson(this object? _obj)
        {
            try
            {
                if (_obj == null) return string.Empty;
                return JsonSerializer.Serialize(_obj, option);
            }
            catch (Exception ex)
            {
                return string.Empty;
            }
        }
        public static object? CopyObjectByType(this object? _obj, Type _type)
        {
            if(_obj==null) return null;
            var sourceType = _obj.GetType();
            var sourcePropperties = sourceType.GetProperties();
            var desery = _type.GetProperties();
            foreach (var item in desery)
            {
                try
                {
                    var _source = sourcePropperties.Where(s => s.Name == item.Name).FirstOrDefault();
                    if (_source != null)
                    {
                        object? value = _source.GetValue(_obj);
                        if (value == null)
                            continue;
                        if (value.GetType().IsCustomClass())
                            item.SetValue(_obj, value.CopyObjectByType(value.GetType()));
                        else if (value.GetType() == typeof(string))
                            item.SetValue(_obj, value.ToString());
                        else if (value.GetType() == typeof(Guid))
                            //bool isGuid = Guid.TryParse(value.ToString(), out Guid result);
                            item.SetValue(_obj, Guid.TryParse(value.ToString(), out Guid result) ? result : Guid.Empty);
                        else
                            item.SetValue(_obj, Convert.ChangeType(value, item.PropertyType));
                    }
                }
                catch (Exception ex)
                {
                    object? type = null;
                    if (item.PropertyType == typeof(string))
                        type = string.Empty;
                    else if (item.PropertyType.IsValueType)
                    {
                        if (item.PropertyType.IsEnum)
                            type = Enum.ToObject(item.PropertyType, 0); // 对于枚举类型，返回零值
                        type = Activator.CreateInstance(item.PropertyType);
                    }
                    item.SetValue(_obj, type);
                }
            }
            return desery;
        }
        public static object? JsonToObject(this string _str, Type _type) {
            try
            {
                object? obj = Activator.CreateInstance(_type);
                if (string.IsNullOrEmpty(_str))
                    return obj;
                obj = JsonSerializer.Deserialize(_str, _type, option);
                return obj;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        public static T JsonToObject<T>(this string _str)
        {
            try { 
                if (string.IsNullOrEmpty(_str))
                    return default(T);
                return JsonSerializer.Deserialize<T>(_str, option)??default(T);
            }
            catch (Exception ex)
            {
                return default(T);
            }
        }




        internal static Dictionary<string, object> FormDataToDictionary(this string _str,string SliptLint)
        {
            Dictionary<string, object> dict = new Dictionary<string, object>();
            List<string> lines = _str.Split(new string[] { SliptLint }, StringSplitOptions.None).Select(s=>s.Replace("--\r\n", string.Empty).Replace("\r\n--", string.Empty)).ToList();
            lines=lines.Where(s=>!string.IsNullOrEmpty(s)&&s!="--").ToList();
            lines.ForEach(s =>
            {
                string[] str = s.Split(new string[] { "\r", "\n", "\t", "\0" }, StringSplitOptions.None).Where(s=>!string.IsNullOrEmpty(s)).ToArray();
                if (str.Length > 0 && str[0].Contains("Content-Disposition: form-data; name="))
                {
                    string[] _title = str[0].Split(new string[] { "form-data;" }, StringSplitOptions.None);
                    if (_title.Length == 2)
                    {
                        _title = _title[1].Split('=');
                        if (_title.Length == 2)
                            if (!dict.ContainsKey(_title[1]))
                                dict.Add(_title[1].Replace("\"",string.Empty), str.Length == 2 ? str[1] : null);
                    }


                }
            });
            return dict;
        }
        internal static bool IsCustomClass(this Type type)
        {
            if(type==typeof(string)) return false;
            return type.IsClass && !type.IsPrimitive && !type.IsValueType && !type.IsEnum;
         }
    }
}
